package com.example.societiesSystem.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @Author：G-L
 * @Version：1.0
 */
public class EncryptUtils {

    // MD5 加密
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : messageDigest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }

    // SHA-256 加密
    public static String sha256(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : messageDigest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not found", e);
        }
    }

    // AES 加密
    public static String aesEncrypt(String input, String key) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            throw new RuntimeException("AES encryption failed", e);
        }
    }

    // AES 解密 key 必须为 16 字节、24 字节、32 字节长度的密钥
    public static String aesDecrypt(String encrypted, String key) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decodedBytes = Base64.getDecoder().decode(encrypted);
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("AES decryption failed", e);
        }
    }

    // 生成 AES 密钥
    public static String generateAesKey(int keySize) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(keySize);
            SecretKey secretKey = keyGenerator.generateKey();
            return Base64.getEncoder().encodeToString(secretKey.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("AES key generation failed", e);
        }
    }

    public static void main(String[] args) {
        // 测试 MD5 加密
        String md5Result = md5("Hello, World!");
        System.out.println("MD5: " + md5Result);

        // 测试 SHA-256 加密
        String sha256Result = sha256("Hello, World!");
        System.out.println("SHA-256: " + sha256Result);

        // 测试 AES 加密和解密
        String aesKey = generateAesKey(128);
        System.out.println("AES Key: " + aesKey);

        String originalText = "Hello, World!";
        String encryptedText = aesEncrypt(originalText, aesKey);
        System.out.println("AES Encrypted: " + encryptedText);

        String decryptedText = aesDecrypt(encryptedText, aesKey);
        System.out.println("AES Decrypted: " + decryptedText);


        System.out.println("-- warning: Please try again!");
        String password = "123456";
        String aesEncrypt = aesEncrypt(password, "1234567890123456");
        System.out.println(aesEncrypt);
        System.out.println(aesDecrypt(aesEncrypt, "1234567890123456"));

    }
}
